
package model
{
    import constants.DialogType;

    import flash.events.ErrorEvent;
    import flash.events.Event;

    import model.service.IElfinService;

    import model.service.UserService;
    import model.vo.ConfigVO;
    import model.vo.UserVO;

    import org.kolonitsky.alexey.StoredFieldManager;

    import view.ElfinStoredFields;

    /**
     *  User proxy store information about current user.
     */
    public class UserProxy extends ElfinSafeProxy
    {
        public static const NAME:String = "UserProxy";

        /**
         *  Dispatched after success or fail authorization request. In succass authorization
         *  notification carry UserVO.
         *
         *  This notification is responce to Config.USER_SIGN_IN/Config.USER_SING_OUT
         *  requests.
         */
        public static const USER_AUTHORIZATION:String = "userProxy_userAuthorization";

        public static const USER_UPDATE:String = "userProxy_userUpdate";
        public static const USER_SIGNOUT:String = "userProxy_signOut";
        public static const PASSWORD_RESTORED:String = "userProxy_passwordRestored";




        //---------------------------------------------------------------------
        //
        // Properties
        //
        //---------------------------------------------------------------------

        //---------------------------------
        // user
        //---------------------------------

        public function get user():UserVO
        {
            return data as UserVO;
        }




        //---------------------------------------------------------------------
        //
        // Methods
        //
        //---------------------------------------------------------------------


        /**
         * @constructor
         */
        public function UserProxy(config:ConfigVO)
        {
            super(NAME, new UserVO(), config);
        }


        /**
         *
         */
        public function checkAuthorization():void
        {
            //If user has authenticity token and already logging.
            if (this.user && this.user.authorized)
            {
                sendNotification(USER_AUTHORIZATION, this.user);
                return;
            }

            var serv:UserService = createUserService(authorization_completeHandler, authorization_faultHandler);
            serv.signin(user);
        }

        public function restorePassword():void
        {
            var serv:UserService = createUserService(restorePassword_completeHandler);
            serv.restorePassword(user);
        }




        /**
         *  Signin function called on application statup for get information
         *  about user authorization status. At first this function receive authenticity
         *  token and retrive user info.
         *
         *  @param user
         */
        public function signin(user:UserVO=null):void
        {
            //If user has authenticity token and already logging.
            if (this.user && this.user.authorized)
            {
                sendNotification(USER_AUTHORIZATION, this.user);
                return;
            }

            var serv:UserService = createUserService(signin_completeHandler);
            serv.signin(user);
        }

        public function signup(user:UserVO=null):void
        {
            var serv:UserService = createUserService(signup_completeHandler);
            serv.signup(user);
        }

        public function signout():void
        {
            var serv:UserService = createUserService(signout_completeHandler);
            serv.signout(user);
        }




        //-------------------------------------------------------------------------
        //
        // Private logic
        //
        //-------------------------------------------------------------------------

        /**
         *
         * @param resultHandler
         * @param faultHandler
         * @return
         */
        private function createUserService(resultHandler:Function,
            faultHandler:Function=null):UserService
        {
            var serv:IElfinService = createElfinService(UserService, resultHandler, faultHandler || errorHandler);
            return serv as UserService;
        }


        //-------------------------------------------------------------------------
        // Event handlers
        //-------------------------------------------------------------------------

        /**
         *
         */
        private function authorization_completeHandler(event:Event):void
        {
            var serv:UserService = event.currentTarget as UserService;
            data = serv.user;
            serv.clear();

            if (this.user && this.user.authorized)
            {
                log("User authorized as " + user.email, 1);
                sendNotification(USER_AUTHORIZATION, this.user);
            }
            else
            {
                log("User " + user.email + " NOT authorized", 2);
                sendNotification(USER_AUTHORIZATION, null);
            }
        }

        /**
         *
         */
        private function restorePassword_completeHandler(event:Event):void
        {
            sendNotification(PASSWORD_RESTORED);
        }


        private function authorization_faultHandler(event:ErrorEvent):void
        {
            switch (event.errorID)
            {
                case  401: //HTTP Unauthorized
                case 1501: //User not logined
                {
                    sendNotification(AppFacade.SHOW_DIALOG, user, DialogType.SIGNIN);
                    break;
                }

                default:
                {
                    sendNotification(AppFacade.SHOW_DIALOG, event, DialogType.ERROR);
                    break;
                }
            }
        }

        /**
         * Respons from server are equal on signin and signup
         * @param event
         */
        private function signin_completeHandler(event:Event):void
        {
            var serv:UserService = event.currentTarget as UserService;

            data = serv.user;
            serv.clear();

            if (this.user && this.user.authorized)
            {
                log("Signin as " + user.email, 1);
                sendNotification(USER_UPDATE, this.user);
                sendNotification(USER_AUTHORIZATION, this.user);
                StoredFieldManager.instance.addItemToList(ElfinStoredFields.USER_NAME, this.user.email);
            }
            else
            {
                log("User " + user.email + " can't be authorized", 2);
                sendNotification(USER_UPDATE, null);
            }
        }

        private function signup_completeHandler(event:Event):void
        {
            signin(user);
        }

        private function signout_completeHandler(event:Event):void
        {
            sendNotification(USER_SIGNOUT);
        }

        private function errorHandler(event:ErrorEvent):void
        {
            sendNotification(AppFacade.SHOW_DIALOG, event, DialogType.ERROR);
        }
    }
}
